<template>
    <div style="padding-left: 4px;padding-right: 8px;">
        <slot name="header" @add="addItem" @remove="removeItem" @update="updateItem"></slot>

        <div :class="bodyClass">
            <el-row v-if="column > 1" :gutter="10">
                <el-col :span="24 / column" v-for="(item, index) in page.records" :key="item">
                    <component v-if="childControl" :is="childControlCmp" v-bind="childAttrs" :disabled="disabled"
                        :item="item" :index="index" @add="addItem" @remove="removeItem" @update="updateItem"></component>
                    <component v-else-if="itemCmp" :is="itemCmp" :item="item" :disabled="disabled" :index="index"
                        @add="addItem" @remove="removeItem" @update="updateItem" @click="clickItem(item)" />
                    <slot v-else :item="item" >{{ item }}</slot>
                </el-col>
            </el-row>
            <template v-else>
                <template v-for="(item, index) in page.records" :key="item">
                    <component v-if="childControl" :is="childControlCmp" v-bind="childAttrs" :disabled="disabled"
                        :item="item" :index="index" @add="addItem" @remove="removeItem" @update="updateItem"></component>
                    <component v-else-if="itemCmp" :is="itemCmp" :item="item" :disabled="disabled" :index="index"
                        @add="addItem" @remove="removeItem" @update="updateItem" @click="clickItem(item)" />
                    <slot v-else :item="item" >{{ item }}</slot>
                </template>
            </template>
        </div>
        <div v-if="!hidePager" >
            <el-pagination :layout="$mbh5 ? pageLayoutH5 : pageLayout" background :pager-count="$mbh5?5:7" 
                v-model:current-page="page.pageIndex" :page-size="page.pageSize" :total="page.totalCount"
                hide-on-single-page style="float: right; padding:6px 0;"></el-pagination>
        </div>

        <el-empty v-if="showEmpty && page.totalCount == 0" description="没有数据" @click="loadData(1)" />

        <slot name="footer" @add="addItem" @remove="removeItem" @update="updateItem"></slot>
    </div>
</template>

<script>
export default {
    name: "MyListBox"
}
</script>

<script setup>
import { ref, watch, getCurrentInstance, defineComponent } from 'vue';
import { Utils } from './main';
import store from './store';
import { useShowHide } from './ShowHide'

const pageSizes = [10, 20, 50, 100, 200];

const props = defineProps({
    action: String,
    modelValue: Array,
    search: Object,
    disabled: Boolean,
    pageLayout: {
        type: String,
        default: 'total, prev, pager, next,jumper',
    },
    pageLayoutH5: {
        type: String,
        default: 'prev, pager, next',
    },
    showEmpty: {
        type: Boolean,
        default: true
    },
    pageSize: {
        type: Number,
        default: 10
    },
    column: {
        type: Number,
        default: 1,
    },
    hidePager: Boolean,
    pkField: {
        type: String,
        default: "ID"
    },
    bodyClass: String,
    childControl: String,
    childAttrs: Object,
    //默认item显示模板
    itemTpl: String,
    //显示过滤函数
    filterFunc: Function,
    //排序(调整显示顺序)函数
    sortFunc: Function,
});




const page = ref({
    pageIndex: 1,
    pageSize: props.pageSize,
    totalCount: 0,
    pageCount: 1,
    records: []
});

const me = getCurrentInstance();

function remoteLoad(pm){
    $server.call(props.action, pm).then((res) => {
        if (Array.isArray(res)) {
            page.value = {
                pageIndex: 1,
                pageSize: res.length || 10,
                pageCount: 1,
                totalCount: res.length,
                records: res
            }
        } else {
            res.pageSize = page.value.pageSize;
            page.value = res;
        }
    });
}

function loadData(pageIndex) {
    pageIndex = pageIndex || page.value.pageIndex || 1;

    if (!props.action) {
        if (props.modelValue) {
            let items = props.modelValue
            if (items && items.length > 0) {
                if (props.filterFunc) {
                    props.filterFunc.bind(me);
                    items = items.filter(props.filterFunc);
                }
                if (props.sortFunc) {
                    items = items.sort(props.sortFunc);
                }
            }
            let pszie = props.pageSize || 10;
            let ptotal = items.length;
            let ppage = Math.ceil(ptotal / pszie);
            let ix = (pageIndex - 1) * pszie;
            page.value = {
                pageIndex: pageIndex,
                pageSize: pszie,
                totalCount: ptotal,
                pageCount: ppage,
                records: items.slice(ix, ix + pszie)
            }
        }
        return;
    };


    let pm = {
        pageIndex,
        pageSize: page.value.pageSize,
    };
    if (store.search2) {
        pm = { pms: props.search, ...pm }
    } else {
        pm = { ...props.search, ...pm }
    }

    remoteLoad(pm);
};


const emit = defineEmits(["update:modelValue", "itemClick"]);

//传入itemTpl模板，生成自定义组件
const itemCmp = props.itemTpl ? defineComponent({
    template: props.itemTpl,
    props: {
        item: Object,
        disabled: Boolean,
        index: Number
    },
    emits: ["add", "remove", "update"],
    ...props.childAttrs
}) : null;


const childControlCmp = props.childControl ? Utils.findComponent(me, props.childControl) : null;

function clickItem(item) {
    emit("itemClick", item);
}



function removeItem(item) {
    let items = props.modelValue || page.value.records;
    let ix = items.indexOf(item);
    let delItems = items.splice(ix, 1);
    if (delItems) {
        page.value.totalCount--;
        emit("update:modelValue", items);
    }
    loadData();
}

function updateItem(item) {
    console.log("updateItem", item);
    let old = page.value.records.filter(p => p[props.pkField] == item[props.pkField])[0];
    if (old) {
        let items = props.modelValue;
        let ix = items.indexOf(old);
        items.splice(ix, 1, item);
        emit("update:modelValue", items);
        loadData();
    }
}

function addItem(item) {
    let old = page.value.records.filter(p => p[props.pkField] == item[props.pkField])[0];
    if (!old) {
        let items = props.modelValue;
        items.push(item);
        page.value.totalCount++;
        emit("update:modelValue", items);
    }
}


watch(() => props.action, (val) => {
    loadData()
})

watch(() => props.search, (newVal, oldVal) => {
    let js1 = JSON.stringify(newVal);
    let js2 = JSON.stringify(oldVal);
    if (js1 != js2) {
        loadData(1);
    }
})

watch(() => props.modelValue, (val) => {
    loadData();
});

watch(() => page.value.pageIndex, (val) => {
    loadData();
});
watch(() => page.value.pageSize, (val) => {
    loadData(1);
});


loadData(1);

defineExpose({
    loadData,
    removeItem,
    addItem,
    updateItem,
});

</script>

